package com.easyspringboot.bulider;

import com.easyspringboot.bean.Constants;
import com.easyspringboot.bean.FieldInfo;
import com.easyspringboot.bean.TableInfo;
import com.easyspringboot.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.List;
import java.util.Map;


/**
 * @Author xiaoyi
 * @Version 1.0
 * @ClassName BuildMapper
 * @Time 3:38
 */
public class BuildServiceImpl {
    private static final Logger logger = LoggerFactory.getLogger(BuildServiceImpl.class);

    public static void execute(TableInfo tableInfo) {
        File folder = new File(Constants.PATH_SERVICE_IMPL);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        File poFile = new File(folder, tableInfo.getBeanName() + Constants.SUFFIX_BEAN_SERVICE_IMPL + ".java");
        OutputStream out = null;
        OutputStreamWriter outw = null;
        BufferedWriter bw = null;
        String beanQueryName = tableInfo.getBeanParamName();
        String beanMapperName = tableInfo.getBeanName()+Constants.SUFFIX_BEAN_MAPPERS;
        try {
            out = new FileOutputStream(poFile);
            outw = new OutputStreamWriter(out, "utf8");
            bw = new BufferedWriter(outw);
            bw.write("package " + Constants.PACKAGE_SERVICE_IMPL + ";");
            bw.newLine();
            bw.write("import javax.annotation.Resource;");
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_MAPPER + "." + tableInfo.getBeanName()+Constants.SUFFIX_BEAN_MAPPERS + ";");
            bw.newLine();
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_SERVICE + "." + tableInfo.getBeanName()+Constants.SUFFIX_BEAN_SERVICE + ";");
            bw.newLine();
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_PO + "." + tableInfo.getBeanName() + ";");
            bw.newLine();
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_QUERY + "." + tableInfo.getBeanParamName() + ";");
            bw.newLine();
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_VO + ".PaginationResultVO;");
            bw.newLine();
            bw.newLine();
            bw.write("import org.springframework.stereotype.Service;");
            bw.newLine();
            bw.newLine();
            bw.write("import java.util.List;");
            bw.newLine();
            bw.newLine();
            bw.write("import "+Constants.PACKAGE_ENUM+".PageSize;");
            bw.newLine();
            bw.newLine();
            bw.write("import "+Constants.PACKAGE_QUERY+".SimplePage;");
            bw.newLine();
            bw.newLine();


            //创建类注释

            BuildComment.createClassComment(bw, tableInfo.getComment() + "Mapper");
            bw.write("@Service(\"" + StringUtils.uperCaseFirstLetter(tableInfo.getBeanName()) + "Service\")");
            bw.newLine();
            bw.write("public class " + tableInfo.getBeanName() + Constants.SUFFIX_BEAN_SERVICE_IMPL + " implements " + tableInfo.getBeanName() + "Service {");
            bw.newLine();
            bw.newLine();
            bw.write("\t@Resource");
            bw.newLine();
            bw.write("\tprivate " + beanMapperName+ "<" + tableInfo.getBeanName() +","+beanQueryName +"> "+ tableInfo.getBeanName()+Constants.SUFFIX_BEAN_MAPPERS + ";");
            bw.newLine();
            bw.newLine();

            bw.write("\t@Override");
            bw.newLine();
            bw.write("//通过" + tableInfo.getBeanParamName() + "查询");
            bw.newLine();
            bw.write("\tpublic List<" + tableInfo.getBeanName() + "> selectByParam(" + tableInfo.getBeanParamName() + " query){");
            bw.newLine();
            bw.write("\t\treturn this."+beanMapperName+".selectList(query);");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.newLine();
            bw.write("\t@Override");
            bw.newLine();
            bw.write("//通过条件查询数量");
            bw.newLine();
            bw.write("\tpublic Integer selectCountByParam(" + beanQueryName+ " query){");
            bw.newLine();
            bw.write("\t\treturn this."+beanMapperName+".selectCount(query);");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.newLine();
            bw.write("\t@Override");
            bw.newLine();
            bw.write("//分页查询");
            bw.newLine();
            bw.write("\tpublic PaginationResultVO<" + tableInfo.getBeanName() + "> findListByPage(" + tableInfo.getBeanParamName() + " query){");
            bw.newLine();
            bw.write("\t\tInteger count = this.selectCountByParam(query);");
            bw.newLine();
            //Long count = this.selectCountByParam(query);
            //		int pageSzie = query.getPageSize() == null? PageSize.SIZE15.getSize():query.getPageSize();
            //		SimplePage page = new SimplePage(query.getPageNo(),count,pageSzie);
            //		List<Article> list = this.selectByParam(query);
            //		PaginationResultVO<Article> resultVO = new PaginationResultVO<>(count,page.getPageSize(),page.getPageNo(),list);
            //		return  resultVO;
            bw.write("\t\tint pageSzie = query.getPageSize() == null? PageSize.SIZE15.getSize():query.getPageSize();");
            bw.newLine();
            bw.write("\t\tSimplePage page = new SimplePage(query.getPageNo(),count,pageSzie);");
            bw.newLine();
            bw.write("\t\tList<" + tableInfo.getBeanName() + "> list = this.selectByParam(query);");
            bw.newLine();
            bw.write("\t\tPaginationResultVO<" + tableInfo.getBeanName() + "> resultVO = new PaginationResultVO<>(count,page.getPageSize(),page.getPageNo(),list);");
            bw.newLine();
            bw.write("\t\treturn  resultVO;");
            bw.newLine();
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.newLine();
            bw.write("\t@Override");
            bw.newLine();
            bw.write("//插入");
            bw.newLine();
            bw.write("\tpublic Integer add(" + tableInfo.getBeanName() + " bean){");
            bw.newLine();
            bw.write("\t\treturn this."+beanMapperName+".insert(bean);");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.newLine();
            bw.write("\t@Override");
            bw.newLine();
            bw.write("//批量插入");
            bw.newLine();
            bw.write("\tpublic Integer addBatch(List<" + tableInfo.getBeanName() + "> list){");
            bw.newLine();
            bw.write("\t\tif(list == null || list.size() == 0){");
            bw.newLine();
            bw.write("\t\t\treturn 0;");
            bw.newLine();
            bw.write("\t\t}");
            bw.newLine();
            bw.write("\t\treturn this."+beanMapperName+".insertBatch(list);");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.write("\t@Override");
            bw.newLine();
            bw.write("//批量插入或更新");
            bw.newLine();
            bw.write("\tpublic Integer addOrUpdateBatch(List<" + tableInfo.getBeanName() + "> list){");
            bw.newLine();
            bw.write("\t\tif(list == null || list.size() == 0){");
            bw.newLine();
            bw.write("\t\t\treturn 0;");
            bw.newLine();
            bw.write("\t\t}");
            bw.newLine();
            bw.write("\t\treturn this."+beanMapperName+".updateOrInsert(list);");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();

            for (Map.Entry<String, List<FieldInfo>> entry : tableInfo.getKeyIndexMap().entrySet()) {
                String methodNameStr = null;
                List<FieldInfo> keyFieldInfos = entry.getValue();//主键字段信息
                Integer index = 0;
                Integer index_annotation = 0;
                StringBuffer methodName = new StringBuffer();//方法名
                StringBuffer annotationName = new StringBuffer();//注解名
                StringBuffer methodParams = new StringBuffer();//方法名
                StringBuffer paramsName = new StringBuffer();//参数名
                for (FieldInfo fieldInfo : keyFieldInfos) {
                    methodName.append(StringUtils.uperCaseFirstLetter(fieldInfo.getPropertyName()));

                    annotationName.append(fieldInfo.getComment());
                    if (index < methodParams.length() - 1) {
                        methodParams.append(",");
                        paramsName.append(",");
                    }
                    if (index_annotation < keyFieldInfos.size() - 1) {
                        annotationName.append(",");
                    }
                    if (index < keyFieldInfos.size() - 1) {
                        methodName.append("And");
                        methodNameStr = methodName.substring(0, methodName.length() - 3);
                    } else {
                        methodNameStr = methodName.toString();
                    }
                    methodParams.append(fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName());
                    paramsName.append(fieldInfo.getPropertyName());
                }
                bw.newLine();
                bw.newLine();
                bw.write("\t@Override");
                bw.newLine();
                bw.write("//通过" + methodNameStr + "查询");
                bw.newLine();
                bw.write("\tpublic " + tableInfo.getBeanName() + " getBy" + methodNameStr + "(" + methodParams + ") {");
                bw.newLine();
                bw.write("\t\treturn this."+beanMapperName+".selectBy" + methodNameStr + "(" + paramsName + ");");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();
                bw.write("\t@Override");
                bw.newLine();
                bw.write("//通过" + methodNameStr + "更新");
                bw.newLine();
                bw.write("\tpublic Integer updateBy" + methodNameStr + "(" + tableInfo.getBeanName() + " bean , " + methodParams + ") {");
                bw.newLine();
                bw.write("\t\treturn this."+beanMapperName+".updateBy" + methodNameStr + "(bean," + paramsName + ");");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();
                bw.write("\t@Override");
                bw.newLine();
                bw.write("//通过" + methodNameStr + "删除");
                bw.newLine();
                bw.write("\tpublic Integer deleteBy" + methodNameStr + "(" + methodParams + ") {");
                bw.newLine();
                bw.write("\t\treturn this."+beanMapperName+".deleteBy" + methodNameStr + "(" + paramsName + ");");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();
            }

            bw.write("}");
            bw.newLine();


        } catch (Exception e) {
            logger.error("创建Service失败", e);
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (outw != null) {
                try {
                    outw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

        }
    }

}

